import { WebcmdMetadataManager } from './webcmd-metadata.manager';
import {
    Component, OnInit, Output, EventEmitter, ViewChild, TemplateRef, ElementRef, ComponentFactoryResolver,
    Injector, ChangeDetectorRef, ApplicationRef, NgZone
} from '@angular/core';
import { BsModalService, BsModalRef, ModalOptions } from '@farris/ui-modal';
import { DialogComponent } from '@farris/ui-dialog';
import { LoadingService } from '@farris/ui-loading';
import { FormBasicService, DesignerEnvType, FarrisMetadata4RefDto, WebCommand, WebCommandMetadata } from '@farris/designer-services';
import { TreeTableComponent } from '@farris/ui-treetable';
import { NotifyService } from '@farris/ui-notify';
import { IdService } from '@farris/ui-common';
import { AppNavigationSelectorComponent } from '@farris/app-navigation-selector';

@Component({
    selector: 'app-command-selector',
    templateUrl: './command-selector.component.html',
    styleUrls: ['./command-selector.component.css'],
    providers: [WebcmdMetadataManager]
})
export class CommandSelectorComponent implements OnInit {
    @ViewChild('modalFooter') modalFooter: TemplateRef<any>;

    selectedCommands: Array<{ cmd: WebCommand, cmp: WebCommandMetadata }>;

    @ViewChild('selector', { read: DialogComponent }) selector: DialogComponent;

    @ViewChild('commandSelector') loadingBox: ElementRef;

    controllers: Array<any>;

    webcmds: WebCommandMetadata[];

    webcmdsData: Array<any> = [];

    // 有可能在打开选择命令的界面时，构件元数据尚未加载，需要显示loading界面，从服务端加载数据
    @Output() commandSelected = new EventEmitter<{
        selectedCommands: Array<{ cmd: WebCommand, cmp: WebCommandMetadata }>,
        newCmds: Array<any>
    }>();

    @Output() closeModal = new EventEmitter<any>();

    webcmdsCols = [{ field: 'name', title: '方法名称' }, { field: 'code', title: '方法编号' }];

    @ViewChild('webcmdsTree') webcmdsTree: TreeTableComponent;

    private app: ApplicationRef;


    // 新增的构件
    newCmds = [];

    constructor(
        private modalService: BsModalService,
        private loading: LoadingService,
        private webcmdManager: WebcmdMetadataManager,
        private formBasicService: FormBasicService,
        private notifyServ: NotifyService,
        private resolver: ComponentFactoryResolver,
        private injector: Injector,
        private idService: IdService,
        private ngZone: NgZone
    ) {
        // this.controllers = actionManager.commandCmps;
        // added by wang-xh: 运行时定制弹出选择构件的窗口后出现数据与页面不同步的现象，故增加强制刷新
        // this.app = this.injector.get(ApplicationRef);
    }

    ngOnInit() {
        this.webcmdsTree.clearAll();
        this.selectedCommands = [];
        this.newCmds = [];

        this.loadCommandData();

        // 监听数据变化
        this.webcmdManager.subscribe(webcmds => {
            this.webcmdsData = [];
            this.selectedCommands = [];
            for (const webcmd of webcmds) {
                const cmdData = {
                    data: {
                        id: webcmd.Id, name: webcmd.Name, code: webcmd.Code, children: [], originalData: webcmd,
                        isController: true
                    },
                    children: [],
                    expanded: true
                };
                this.webcmdsData.push(cmdData);
                if (webcmd.Commands) {
                    for (const command of webcmd.Commands) {
                        const operationData = {
                            data: {
                                id: this.idService.generate(), // 部分构件下的命令id是重复的，影响了树表的勾选，故此处重置id
                                name: command.Name, code: command.Code, children: [], originalData: command,
                                isController: false
                            },
                            children: []
                        };
                        cmdData.children.push(operationData);
                    }
                }
            }

            // 因为命令的id都重置了，treetable就没法默认勾选上次的行，所以执行一次clearAll
            this.webcmdsTree.clearAll();

            this.webcmdsData = this.unique(this.webcmdsData);
            this.webcmdsTree.loadData(this.webcmdsData);
        });
    }

    unique(arr: Array<any>): Array<any> {
        const result = [];
        let existToken = false;
        arr.forEach(item => {

            const isExisted = result.find(res => res.data && item.data.id === res.data.id);
            if (!isExisted) {
                result.push(item);
            } else {
                existToken = true;
            }
        });
        // 暂时屏蔽
        // if (existToken) {
        //   alert('相同的动作构件已经存在');
        // }
        //
        return result;
    }


    openMetadataSelector() {
        const compFactory = this.resolver.resolveComponentFactory(AppNavigationSelectorComponent);
        // 依赖注入
        const compRef = compFactory.create(this.injector);
        // 配置模态框参数
        compRef.instance.editorParams = {
            relativePath: this.formBasicService.formMetaBasicInfo.relativePath,
            envType: this.formBasicService.envType
        };
        /** 弹窗相关设置 */
        const modalConfig: ModalOptions = {
            title: '选择内置控制器',
            width: 900,
            height: 500,
            resizable: false,
            showButtons: false,
            showMaxButton: false,
            minWidth: 700,
            minHeight: 400,
        };
        const modalPanel: BsModalRef = this.modalService.show(compRef, modalConfig);
        modalPanel.content.closeModal.subscribe(() => {
            modalPanel.close();
        });
        modalPanel.content.submitModal.subscribe(data => {
            this.metadataSelected(data);
            modalPanel.close();
        });
    }


    /**
     * 处理构件元数据选择后的逻辑
     */
    metadataSelected(metadata4RefDto: FarrisMetadata4RefDto) {
        const metadata = metadata4RefDto.metadata;
        const newCmd = this.webcmdManager.addCmdMetadata(metadata);

        // 新构件
        if (newCmd && !this.newCmds.find(c => c.id === newCmd.id)) {
            this.newCmds.push(newCmd);
        }
    }

    confirm() {
        if (this.webcmdsTree.checkeds.length === 0) {
            this.notifyServ.warning('请先选择方法');
            return;
        }
        const newCmds = [];
        this.webcmdsTree.checkeds.forEach(selection => {
            // 去除控制器节点
            if (selection.data.isController) {
                return;
            }
            this.selectedCommands.push({ cmd: selection.data.originalData, cmp: selection.parent.data.originalData });

            const n = this.newCmds.find(c => c.id === selection.parent.data.originalData.Id);
            if (n) {
                newCmds.push(n);
            }
        });
        this.commandSelected.emit({
            selectedCommands: this.selectedCommands,
            newCmds
        });
    }

    cancel() {
        this.closeModal.emit();
    }


    cmdTreeNodeClicked({ node }: any) {
        // // 记录选中的命令，如果选中的是构件节点，把选中命令置为空，以禁用确定按钮
        // if (node.level === 2) {
        //   // 选中的是命令节点
        //   this.selectedCommand = { cmd: node.originalData, cmp: node.parent.originalData };
        // } else {
        //   this.selectedCommand = null;
        // }
    }



    private loadCommandData() {
        const loadingComp = this.loading.show({ container: this.loadingBox });

        this.webcmdManager.loadCmdWithDom().subscribe(() => {
            loadingComp.close();
        });
    }
}
